#define _GNU_SOURCE      // 启用GNU扩展功能（如clone函数的扩展参数）
#include <errno.h>       // 用于错误码处理（errno）
#include <sched.h>       // 用于clone系统调用
#include <stdio.h>       // 用于输入输出（fprintf等）
#include <string.h>      // 用于字符串操作（strerror等）
#include <sys/wait.h>    // 用于等待子进程（waitpid、WEXITSTATUS）
#include <unistd.h>      // 用于execvp函数

#define STACKSIZE (1024 * 1024)  // 子进程栈大小（1MB）

static char stack[STACKSIZE];  // 子进程的栈空间（栈是向下增长的）

void print_err(char const *const reason) {
  fprintf(stderr, "Error %s: %s\n", reason, strerror(errno));
}

int exec(void *args) {
  char **const argv = args;  // args是main中传入的命令参数（如["/bin/sh", NULL]）
  if (execvp(argv[0], argv) != 0) {  // 替换当前进程为目标命令
    print_err("executing command");
    return 1;
  }
  return 0;
}

int main(int argc, char **argv) {
  // 检查参数：必须提供要执行的命令（如./program /bin/sh）
  if (argc < 2) {
    fprintf(stderr, "No command specified\n");
    return 1;
  }

  // 命名空间标志：指定需要隔离的资源类型
  const int flags = CLONE_NEWNET | CLONE_NEWUTS | CLONE_NEWNS |
                    CLONE_NEWIPC | CLONE_NEWPID | CLONE_NEWUSER |
                    CLONE_NEWCGROUP | SIGCHLD;

  // 创建子进程（带命名空间隔离）
  pid_t pid = clone(exec, stack + STACKSIZE, flags, &argv[1]);
  if (pid < 0) {
    print_err("calling clone");
    return 1;
  }

  // 等待子进程结束并获取退出状态
  int status = 0;
  if (waitpid(pid, &status, 0) == -1) {
    print_err("waiting for pid");
    return 1;
  }

  // 返回子进程的退出码
  return WEXITSTATUS(status);
}